﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

using MyUtils;

namespace XTrace.Viewer.Filter
{
	public interface IGraphChanged
	{
		void InvokeGraphChanged(object node, string property);
	}

	public class FilterModel : ObservableObject, IGraphChanged
	{
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public string FileName { get; set; }

		string _displayName;

		public string DisplayName
		{
			get { return _displayName; }
			set
			{
				_displayName = value;
				OnPropertyChanged("DisplayName");
			}
		}

		string _filterInfoRegex;

		[DefaultValue(null)]
		public string FilterInfoRegex
		{
			get { return _filterInfoRegex; }
			set
			{
				_filterInfoRegex = value;
				OnPropertyChanged("FilterInfoRegex");
			}
		}

		int _filterProcessId;

		[DefaultValue(0)]
		public int FilterProcessId
		{
			get { return _filterProcessId; }
			set
			{
				_filterProcessId = value;
				OnPropertyChanged("FilterProcessId");
			}
		}

		int _filterThreadId;

		[DefaultValue(0)]
		public int FilterThreadId
		{
			get { return _filterThreadId; }
			set
			{
				_filterThreadId = value;
				OnPropertyChanged("FilterThreadId");
			}
		}

		[DefaultValue(null)]
		[Obsolete("Use GetStringSetFilter", true)]
		public string FilterProcessName
		{
			get { return null; }
			set
			{
			}
		}

		[DefaultValue(null)]
		[Obsolete("Use GetStringSetFilter", true)]
		public string FilterThreadName
		{
			get { return null; }
			set
			{
			}
		}

		[DefaultValue(null)]
		[Obsolete("Use GetStringSetFilter", true)]
		public string FilterProject
		{
			get { return null; }
			set
			{
			}
		}

		[DefaultValue(null)]
		[Obsolete("Use GetStringSetFilter", true)]
		public string FilterSourceName
		{
			get { return null; }
			set
			{
			}
		}

		[Obsolete("Use GetStringSetFilter", true)]
		[DefaultValue(null)]
		public StringSetFilter EventIds
		{
			get { return null; }
			set
			{
				value.Parent = this;
				_stringSetFilters["EventId"] = value;
			}
		}

		public StringSetFilter GetStringSetFilter(string proeprtyName)
		{
			StringSetFilter ssf;
			return _stringSetFilters.TryGetValue(proeprtyName, out ssf) ? ssf : (_stringSetFilters[proeprtyName] = new StringSetFilter(this) {UseIncludes = true});
		}

		readonly IDictionary<string, StringSetFilter> _stringSetFilters = new Dictionary<string, StringSetFilter>();

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public IDictionary<string, StringSetFilter> StringSetFilters
		{
			get { return _stringSetFilters; }
		}

		public void Init()
		{
			foreach (var stringSetFilter in StringSetFilters.Values)
			{
				stringSetFilter.Parent = this;
			}
		}

		public override string ToString()
		{
			return DisplayName;
		}

		void IGraphChanged.InvokeGraphChanged(object node, string property)
		{
			IsDirty = true;
		}

		protected new virtual void OnPropertyChanged(string name)
		{
			base.OnPropertyChanged(name);
			((IGraphChanged)this).InvokeGraphChanged(this, name);
		}

		bool _isDirty;

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public bool IsDirty
		{
			get { return _isDirty; }
			internal set
			{
				if (_isDirty != value)
				{
					_isDirty = value;
					base.OnPropertyChanged("IsDirty");
				}
			}
		}
	}

//	class FilterModelLite
//	{
//		private readonly string _filePath;
//		private readonly string _displayName;
//		private readonly FilterStorage _storage;
//		private readonly Lazy<FilterModel> _model;
//
//		public FilterModelLite(string filePath, string displayName, FilterStorage storage)
//		{
//			_filePath = filePath;
//			_displayName = displayName;
//			_storage = storage;
//			_model = new Lazy<FilterModel>(() => _storage.Load(_filePath));
//		}
//
//		public override string  ToString()
//		{
//			return _displayName;
//		}
//
//		public FilterModel Model
//		{
//			get { return _model.Value; }
//		}
//	}
}
